

package TransportProblem;

import java.util.HashMap;
import java.util.Map;

public class Route {

	private Map<Integer, Customers> route;
	private int load;
	private double distance;
	private double ttt_of_route;
	private double vio_of_route;
	private double vio_of_dur;
	private int vio_of_load;
	private double evalVal;
	private double waitingTime;
	private double capacity;
	private double vio_of_TW;
	
	public Route() {
		
		this.route = new HashMap<Integer, Customers>();
	}
	
	public Route(Map<Integer, Customers> r) {
		
	}
	
	public Route deepClone(){
		Route r = new Route();
		for(int i = 0; i < route.size();i++){
			r.getRoute().put(i, route.get(i).deepClone());
		}
		r.setLoad(load);
		r.setDistance(distance);
		r.setTtt_of_route(ttt_of_route);
		r.setVio_of_dur(vio_of_dur);
		r.setVio_of_route(vio_of_route);
		r.setVio_of_load(vio_of_load);
		r.setEvalVal(evalVal);
		r.setWaitingTime(waitingTime);
		r.setCapacity(capacity);
		r.setVio_of_TW(vio_of_TW);
		return  r;
	}
	public double getVio_of_TW() {
		return vio_of_TW;
	}
	
	public void insertIntoRouteInterger(Map<Integer, Integer> route, int position, int elementToInsert, Data d, boolean definitInsert){
		int cust = 0;
		int tempCust = 0;
		if(!definitInsert){
			if(position != route.size()){
				cust = route.get(route.get(0) + position);
				route.remove(route.get(0) + position);
				route.put(route.get(0) + position, d.getCustomerByName(elementToInsert).getName());
				
				
				for(int u = position + 1; u < route.size();u++){
					tempCust = route.get(u);
					route.remove(u);
					route.put(route.get(0) + u, d.getCustomerByName(cust).getName());
					cust = tempCust;
				}
				route.put(route.size(), d.getCustomerByName(cust).getName());
			}else
				{
					cust = route.get(position);
					route.remove(route.get(position) + position);
					route.put(route.get(0) + position, d.getCustomerByName(elementToInsert).getName());
					route.put(route.get(0) + position + 1, d.getCustomerByName(cust).getName());
				}
		}else
			if(route.size() > position){ //Damit an der richtigen Stelle mit dem richtigen Index inserted wird
				if(position != route.size()){
					cust = route.get(route.get(0) + position);
					route.remove(route.get(0) + position);
					route.put(route.get(0) + position, d.getCustomerByName(elementToInsert).getName());
					
					
					for(int u = position + 1; u < route.size();u++){
						tempCust = route.get(u);
						route.remove(u);
						route.put(route.get(0) + u, d.getCustomerByName(cust).getName());
						cust = tempCust;
					}
					route.put(route.size(), d.getCustomerByName(cust).getName());
				}else
					{
						cust = route.get(position);
						route.remove(route.get(position) + 1); //definitInsert greift f�r hier + 1
						route.put(route.get(0) + position, d.getCustomerByName(elementToInsert).getName());
						route.put(route.get(0) + position + 1, d.getCustomerByName(cust).getName());
					}
			}else
					route.put(route.size(), elementToInsert); //falls position >= route.size() wird das Element am Schluss angeh�ngt
			
	}
	
	public void insertIntoRouteCustomer(Map<Integer, Customers> route, int position, Customers elementToInsert, Data d, boolean definitInsert){
		int cust = 0;
		int tempCust = 0;
		if(!definitInsert){	
			//System.out.println("Position: " + (0 + position)  + " Customer to Insert: " + elementToInsert + " Route: " + route.size());
			if(position != route.size()){ //�nderung !!!!!!!!!!!!!!!!!!!!!!!!!!!!
				cust = route.get(position).getName();
				route.remove(position);
				route.put(position, elementToInsert);
				
				
				for(int u = position + 1; u < route.size();u++){
					tempCust = route.get(u).getName();
					route.remove(u);
					route.put(u, d.getCustomerByName(cust));//remove deepclone
					cust = tempCust;
				}
				route.put(route.size(), d.getCustomerByName(cust));//remove deepclone
			}else
				{
					cust = route.get(position).getName();
					route.remove(route.get(position).getName() + position); //Depot l�schen
					route.put(position, elementToInsert);
					route.put(position + 1, d.getCustomerByName(cust));//remove deepclone
				}
		}else{
			if(route.size() > position){ //Damit an der richtigen Stelle mit dem richtigen Index inserted wird
				if(position != route.size()){ //�nderung !!!!!!!!!!!!!!!!!!!!!!!!!!!!
					//cust = route.get(route.get(0).getName() + position).getName();
					cust = route.get(position).getName();
					route.remove(position);
					route.put(position, elementToInsert);
					
					System.out.println("Variable Position:" + position);
				
//					System.out.println("Route size()" + route.size());
					for(int u = position + 1; u < route.size();u++){
						tempCust = route.get(u).getName();
						route.remove(u);
						route.put(u, d.getCustomerByName(cust));//remove deepclone
						cust = tempCust;
					}
					route.put(route.size(), d.getCustomerByName(cust)); 
				}else
					{
						cust = route.get(position).getName();
						route.remove(route.get(position).getName() + 1); //definitInsert greift f�r hier + 1
						route.put(position, elementToInsert);
						route.put(position + 1, d.getCustomerByName(cust)); // removed deepclone
					}
			}else
				route.put(route.size(), elementToInsert); //falls position >= route.size() wird das Element am Schluss angeh�ngt
		}
	}
	
	
	public void eraseElementFromRouteInteger(Map<Integer, Integer> route, int positionToDelete, Data d){
		int cust = 0;
		int tempCust = 0;
		
		for(int u = positionToDelete; u < route.size() - 1;u++){
			route.remove(u);
			route.put(u, d.getCustomerByName(route.get(u + 1)).getName());
			route.remove(u +1);
			
		}
		if(route.size() > 2 && route.size() - 1 != positionToDelete){
			cust = route.size();
			route.remove(route.size());
			route.put(route.size(), d.getCustomerByName(0).getName());
		}
	}
	
	public void eraseElementFromRouteCostumers(Map<Integer, Customers> route, int positionToDelete, Data d){
		int cust = 0;
		int tempCust = 0;
		
		for(int u = positionToDelete; u < route.size() - 1;u++){
			route.remove(u);
			route.put(u, d.getCustomerByName(route.get(u + 1).getName()).deepClone());
			route.remove(u +1);
			
		}
		if(route.size() > 2 && route.size() - 1 != positionToDelete){
			cust = route.size();
			route.remove(route.size());
			route.put(route.size(), d.getCustomerByName(0).deepClone());
		}
	}

	public void setVio_of_TW(double vio_of_TW) {
		this.vio_of_TW = vio_of_TW;
	}

	public void addCustomerbyName(Customers c){
		route.put(c.getName(), c);
	}
	public void addCustomerbyNameSameCusotmerNextPosition(Customers c){
		route.put(c.getName() + 1, c);
	}
	
	
	public Map<Integer, Customers> getRoute() {
		return route;
	}
	public void setRoute(Map<Integer, Customers> route) {
		this.route = route;
	}
	public int getLoad() {
		return load;
	}
	public void setLoad(int load) {
		this.load = load;
	}
	public double getDistance() {
		return distance;
	}
	public void setDistance(double distance) {
		this.distance = distance;
	}
	public double getTtt_of_route() {
		return ttt_of_route;
	}
	public void setTtt_of_route(double ttt_of_route) {
		this.ttt_of_route = ttt_of_route;
	}
	public double getVio_of_route() {
		return vio_of_route;
	}
	public void setVio_of_route(double vio_of_route) {
		this.vio_of_route = vio_of_route;
	}
	public double getVio_of_dur() {
		return vio_of_dur;
	}
	public void setVio_of_dur(double vio_of_dur) {
		this.vio_of_dur = vio_of_dur;
	}
	public int getVio_of_load() {
		return vio_of_load;
	}
	public void setVio_of_load(int vio_of_load) {
		this.vio_of_load = vio_of_load;
	}
	public double getEvalVal() {
		return evalVal;
	}
	public void setEvalVal(double evalVal) {
		this.evalVal = evalVal;
	}
	public double getWaitingTime() {
		return waitingTime;
	}
	public void setWaitingTime(double waitingTime) {
		this.waitingTime = waitingTime;
	}

	public double getCapacity() {
		return capacity;
	}

	public void setCapacity(double capacity) {
		this.capacity = capacity;
	}
	
	
	
	
}
